home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.5 Applications 2002 November / SGI IRIX 6.5 Applications 2002 November.iso / dist / gateway.idb / usr / WebFace / Source / 20-NetworkServices / dns / named-config.frm.z / named-config.frm
Encoding:
Text File  |  2002-06-12  |  17.6 KB  |  614 lines

  1. #!/usr/bin/perl5
  2. #
  3. # named-config.cgi
  4. #
  5. # Copyright 1988-1996 Silicon Graphics, Inc.
  6. # All rights reserved.
  7. #
  8. # This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  9. # the contents of this file may not be disclosed to third parties, copied or
  10. # duplicated in any form, in whole or in part, without the prior written
  11. # permission of Silicon Graphics, Inc.
  12. #
  13. # RESTRICTED RIGHTS LEGEND:
  14. # Use, duplication or disclosure by the Government is subject to restrictions
  15. # as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  16. # and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  17. # successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  18. # rights reserved under the Copyright Laws of the United States.
  19. #
  20. # $Id: named-config.frm,v 1.49 1998/04/06 21:36:37 jrw Exp $
  21.  
  22. require "/usr/OnRamp/lib/OnRamp.pm";
  23. require "/usr/OnRamp/lib/java.pm";
  24.  
  25. $conf = "/etc/named.boot";
  26. $dummy = "/etc/named.boot.dummy";
  27. $myname = "named-config.cgi";
  28. $help_page = "named-config-help.html";
  29. $title = "Domain Name Server";
  30.  
  31. # note; this does not match AccountForm prototype
  32. # since it also requires the runOK() routine.
  33. # also, testDomain is unique in that it allows
  34. # IN-ADDR.ARPA domains...
  35. $js_main =
  36. "$js_error_box
  37. $js_help
  38. $js_hostname
  39. $js_iplist
  40. $js_ip
  41. which = \"none\";
  42. function runSubmit() {
  43.     if(which == \"add\") return runAdd();
  44.     if(which == \"edit\") return runEdit();
  45.     if(which == \"delete\") return runDelete();
  46.     if(which == \"ok\") return runOK();
  47.     return (true);
  48. }    
  49. function markAdd() { which = \"add\"; }
  50. function markEdit() { which = \"edit\"; }
  51. function markDelete() { which = \"delete\"; }
  52. function markOK() { which = \"ok\"; }
  53. function markOther() { which = \"none\"; }
  54. function runAdd()  {
  55.     form = document.DNSForm;
  56.     if (!testDomain(form.newDomain)) return (false);
  57.     return (true);
  58. }
  59. function runEdit()  {
  60.     Ctrl = document.DNSForm.chosen;
  61.     none = true;
  62.     for(i = 0; i < Ctrl.length; i++) { if (Ctrl.options[i].selected) { none = false; break; } }
  63.     if(none) { errorBox (Ctrl, \"To edit an existing domain, first select a domain \\nfrom the list, then click the edit button.\"); return (false); }
  64.     return (true);
  65. }
  66. function runDelete()  {
  67.     Ctrl = document.DNSForm.chosen;
  68.     none = true;
  69.     for(j = 0; j < Ctrl.length; j++) { if (Ctrl.options[j].selected) { none = false; break; } }
  70.     if(none) { errorBox (Ctrl, \"To delete an existing domain, first select a domain \\nfrom the list, then click the delete button.\"); return (false); }
  71.     return (true);
  72. }
  73. function runOK()  {
  74.     form = document.DNSForm;
  75.     if (!testIPList(form.forwarders, \"forwarder\")) return (false);
  76.     return (true);
  77. }
  78.  
  79. function createArray(num) {
  80.     this.length = num;
  81.     for (var j = 0; j < num; j++) { this[j] = 0; }
  82. }
  83.  
  84. function testDomain(Ctrl) {
  85.     nums = \"0123456789\";
  86.     arpa_num = 0; i = 0;
  87.     st_num = false;
  88.  
  89.     p_places = new createArray(4);
  90.  
  91.     if (Ctrl.value == \"\") { 
  92.     errorBox (Ctrl, \"To add a new domain, first enter \\nthe domain name.\"); 
  93.     return (false); 
  94.     }
  95.    
  96.     for(i=0; i<nums.length; i++)
  97.     if (Ctrl.value.charAt(0) == nums.charAt(i)) st_num = true; 
  98.  
  99.     if (st_num) {
  100.     arpa_num = 0;
  101.     for(i=0; i<Ctrl.value.length; i++)
  102.         if (Ctrl.value.charAt(i) == \"I\" || Ctrl.value.charAt(i) == \"i\") arpa_num = i;
  103.     if (arpa_num == 0) { 
  104.         errorBox (Ctrl, \"The domain name \" + Ctrl.value + \"\\nis invalid.\"); 
  105.         return (false); 
  106.     }
  107.     rev_ip = Ctrl.value.substring(0, arpa_num - 1);
  108.     arpa_str = Ctrl.value.substring(arpa_num, Ctrl.value.length);
  109.  
  110.     arpa_str = arpa_str.toUpperCase();
  111.     if (arpa_str != \"IN-ADDR.ARPA\") {
  112.         errorBox (Ctrl, \"The domain name \" + Ctrl.value + \"\\nis invalid.\");
  113.         return (false);
  114.     }
  115.  
  116.     p_places[0] = -1;
  117.     num_periods = 0;
  118.     for (i=0; i<rev_ip.length; i++) {
  119.         if (rev_ip.charAt(i) == \".\") {
  120.         num_periods++;
  121.         p_places[num_periods] = i;
  122.         }
  123.     }
  124.  
  125.     unrev_ip = rev_ip.substring(p_places[num_periods] + 1, rev_ip.length);
  126.     for (i=num_periods; i>=1; i--)
  127.         unrev_ip = unrev_ip + \".\" + rev_ip.substring(p_places[i-1]+1,p_places[i]); 
  128.  
  129.     if (!testIPaddress(unrev_ip, false)) {
  130.         errorBox(Ctrl, \"The domain name \" + Ctrl.value + \"\\nis invalid.\");
  131.         return (false);
  132.     }
  133.  
  134.     } else {
  135.     if (!testHostname(Ctrl, Ctrl.value, \"domain name\", 0))
  136.         return (false); 
  137.     }
  138.     return (true);
  139. }";
  140.  
  141. $js_add =
  142. "$js_standard
  143. $js_error_box
  144. $js_help
  145. $js_filename
  146. $js_ip
  147. $js_iplist
  148. function checkForm(form)  {
  149.     if (!testFilename(form.newFile, \"file name\")) return (false);
  150.     if (form.list.value == \"\" && form.newType.options[1].selected) {
  151.         errorBox (form.list, \"A list of server addresses is \"
  152.             + \"required \\nfor the secondary domain.\");
  153.         return (false);
  154.     }
  155.     if (!testIPList(form.list, \"server address\")) return (false);
  156.     return (true);
  157. }";
  158.  
  159. $js_edit = 
  160. "$js_standard
  161. $js_error_box
  162. $js_help
  163. $js_filename
  164. $js_ip
  165. $js_iplist
  166. function checkForm(form)  {
  167.     if (!testFilename(form.newFile, \"file name\")) return (false);
  168.     if (form.list.value == \"\" && form.type.options[1].selected) {
  169.         errorBox (form.list, \"A list of server addresses is \"
  170.             + \"required \\nfor the secondary domain.\");
  171.         return (false);
  172.     }
  173.     if (!testIPList(form.list, \"server address\")) return (false);
  174.     return (true);
  175. }";
  176.  
  177.  
  178. print "Content-type: text/html\n\n";
  179.  
  180. &get_fields;
  181.  
  182. $srv_on = get_config("named");
  183.  
  184. $edit = 0;
  185. $delete = 0;
  186.  
  187. &getDomains;
  188.  
  189. if (%fld) {
  190.     $fld{'chosen'} =~ /([\w.-]+)/;
  191.     $fld{'chosen'} = $1;
  192.  
  193.     $help = $document_root . $ENV{"SCRIPT_NAME"};
  194.     $help =~ s/cgi$/hlp/;
  195.     exec $help if ($fld{'help'} eq "Help");
  196.  
  197.     if ($fld{'doit'} eq 'Ok') {
  198.         if ($srv_on ne $fld{'server'}) { &changeStatus; }
  199.         if ($fld{'delFile'}) { &delete($fld{'delFile'}); }
  200.         &checkForwarders;
  201.         &checkSlave;
  202.         if (!$message) { 
  203.             if (!$fld{'newDomain'}) { $message = "No changes made."; }
  204.             else { $message = qq|To add a new domain, click the "Add New Domain"
  205.                    button.|; }
  206.         }
  207.     }
  208.     elsif ($fld{'add'}) { 
  209.         &formValid_add;
  210.         $val{'domain'} = $fld{'newDomain'};
  211.         $val{'type'} = $type; 
  212.         &getAdd; 
  213.     }
  214.     elsif ($fld{'delete'}) {
  215.         &error(0,"No domain selected.") if !$fld{'chosen'};
  216.         $message = qq|Click "Ok" to save changes.|; 
  217.         $delete = 1; 
  218.     }
  219.     elsif ($fld{'doAdd'} eq 'Ok') { &formValid_doAdd; &addDomain; &getDomains; }
  220.     elsif ($fld{'doEdit'} eq 'Ok') { &formValid_doEdit; &editDomain; &getDomains; }
  221.     elsif ($fld{'edit'}) {
  222.         &error(0,"No domain selected.") if !$fld{'chosen'}; 
  223.         &getDomains($fld{'chosen'});
  224.         &putEdit;
  225.         &getEdit;
  226.         $edit = 1;
  227.     }
  228.     else { $message = "Use buttons to submit form."; &generic; exit 0; }
  229. }
  230.  
  231. if (($fld{'add'} ne 'Add New Domain') && ($edit == 0)) {
  232.     if (-e "/usr/sbin/named") { &generic; }
  233.     else { 
  234.         &title_block($title);
  235.         &header_block($title);
  236.         print "<i>The domain name server software is not installed on this
  237.         machine.  Install subsystem </i><b>eoe.sw.named</b><i>
  238.         from the distribution CD.</i>";
  239.     }   
  240. }
  241.  
  242. sub checkSlave {
  243.     if ($val{'slave'} ne $fld{'slave'}) {
  244.         if ($fld{'slave'} eq 'Yes') {
  245.             open(OUT,">> $conf");
  246.             print OUT "slave\n";
  247.             close(OUT);
  248.             $val{'slave'} = 'Yes';
  249.             $message = "Dynamic creation of direct links disabled.";
  250.         } else {
  251.             open(IN,"< $conf");
  252.             open(OUT,"> $dummy");
  253.             while(<IN>) {
  254.                 @items = split(/\s+/);
  255.                 if ($items[0] ne 'slave') { print OUT $_; }
  256.             }
  257.             close(IN);
  258.             close(OUT);
  259.             rename($dummy,$conf);
  260.             $val{'slave'} = 'No';
  261.             $message = "Dynamic creation of direct links enabled.";
  262.         }
  263.     }
  264. }
  265.  
  266. sub changeStatus {
  267.     if($fld{'server'} eq 'Yes') { 
  268.     system("/etc/chkconfig", "named", "on");
  269.     system("/usr/sbin/named.restart");
  270.         $srv_on = "Yes"; 
  271.         $message = "Name server enabled.";
  272.     }
  273.     else { 
  274.     system("/etc/chkconfig", "named", "off");
  275.     system("/etc/killall", "named");
  276.         $srv_on = "No";
  277.         $message = "Name server disabled.";
  278.     }
  279. }
  280.  
  281. sub formValid_add {
  282.     &error(0,"Cannot add duplicate domain name.") 
  283.         if grep($_ eq $fld{'newDomain'},@domainList);
  284.     &error(0,"Invalid domain name.") 
  285.     if $fld{'newDomain'} =~ /^\s+$/;
  286. #    if (! ( $fld{'newDomain'} =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)\.in-addr\.arpa/ )) {
  287. #        &error(0,"Invalid domain name.") if &check_hostname($fld{'newDomain'});
  288. #    } else {
  289. #        $reverse = "$4.$3.$2.$1";
  290. #        &error(0,"Invalid IP address: $reverse.") if &check_ipaddr($reverse);
  291. #    }
  292. }
  293.  
  294. sub formValid_doAdd {
  295.     my $erval = &check_fname($fld{'newFile'});
  296.     &error(1,$erval) if $erval;
  297.  
  298.     if ($fld{'newType'} eq 'secondary') {
  299.         &error(1,"Server addresses required for secondary domain.") 
  300.             if !$fld{'list'};
  301.         @list = split(/[\n\s]+/,$fld{'list'});
  302.         foreach $arg (@list) {
  303.             &error(1,"Invalid IP address: $arg.") if &check_ipaddr($arg);
  304.         }
  305.     }
  306. }
  307.  
  308. sub formValid_doEdit {
  309.     my $erval = &check_fname($fld{'newFile'});
  310.     &error(2,$erval) if $erval;
  311.  
  312.     if ($fld{'type'} eq 'secondary') {
  313.         &error(2,"Server addresses required for secondary domain.") 
  314.             if !$fld{'list'};
  315.         @list = split(/[\n\s]+/,$fld{'list'});
  316.         foreach $arg (@list) {
  317.             &error(2,"Invalid IP address: $arg.") if &check_ipaddr($arg);
  318.         }
  319.     }
  320. }
  321.  
  322. sub error {
  323.     $mes = $_[1];
  324.     $send = $_[0];
  325.     &error_block($mes);
  326.     %val = %fld;
  327.     if ($send == 0) { &generic; }
  328.     elsif ($send == 1) { &getAdd; }
  329.     elsif ($send == 2) { &getEdit; }
  330.     exit 0;
  331. }
  332.  
  333. sub editDomain {
  334.     open(IN,"< $conf");
  335.     open(OUT,"> $dummy");
  336.  
  337.     while(<IN>) {
  338.         $line = $_;
  339.         @items = split(/\s+/,$line);
  340.         if ($items[1] ne $fld{'chosen'}) { print OUT $line; next; }
  341.         else { 
  342.             print OUT "; $line";
  343.         }   
  344.     }
  345.  
  346.     $numTab1 = 2 - length($fld{'type'})/8;
  347.     $numTab2 = 4 - length($fld{'domain'})/8;
  348.  
  349.     print OUT $fld{'type'};
  350.  
  351.     for ($i=0;$i<$numTab1;$i++) { print OUT "\t"; }
  352.     print OUT $fld{'chosen'};
  353.     if ($fld{'type'} eq 'primary') {
  354.         for ($i=0;$i<$numTab2;$i++) { print OUT "\t"; }
  355.     } else {
  356.         print OUT " ";
  357.         foreach $arg (@list) {
  358.             print OUT "$arg ";
  359.         }
  360.     }
  361.     print OUT "$fld{'newFile'}\n";    
  362.  
  363.     close(IN);
  364.     close(OUT);
  365.     rename($dummy, $conf);
  366.     $message = "Domain edited.";
  367. }
  368.  
  369. sub putEdit {
  370.     $val{'newFile'} = $file;
  371.     $val{'list'} = "";
  372.     foreach $arg (@listServe) {
  373.         $val{'list'} .= "$arg\n";
  374.     }
  375. }
  376.  
  377. sub getEdit {
  378.     $num = $_[0];
  379.  
  380.     &js_title_block($title,$js_edit);
  381.     &header_block("Edit Domain");
  382.  
  383.     print "<form name=StandardForm action=$myname method=post onSubmit=\"return runSubmit()\">";
  384.     print "<center><table>";
  385.  
  386.     print "<input type=hidden name=chosen value=$fld{'chosen'}>";
  387.     print "<input type=hidden name=type value=$val{'type'}>";
  388.  
  389.     print "<tr><th align=left>Domain name:</th><td><tt>$fld{'chosen'}</tt></td></tr>";
  390.     print "<tr><th align=left>Name server type:</th><td><tt>$val{'type'}</tt></td></tr>";
  391.  
  392.     print "<tr><th align=left>File name for domain information:</th><td>";
  393.     print &text("newFile",$val{'newFile'},21);
  394.     print "</td></tr>\n";
  395.  
  396.     if ($fld{'type'.$num} ne 'primary') {
  397.         print "<tr><th align=left valign=top>List of server addresses:</th>";
  398.         print "<td><textarea name=list rows=5 cols=20>";
  399.         print $val{'list'};
  400.         print "</textarea></td>";
  401.         print "</tr>\n";
  402.     }
  403.     print "</table></center><br>";
  404.  
  405.     print "<i>  Note:  server address list required only for secondary domains.</i><br><br>";
  406.  
  407.     print &js_buttons('doEdit','Ok','onClick="markOK()"',
  408.         'onClick="markOther()"',
  409.         "onClick=\"do_help('$help_page'); return (false)\"");
  410.  
  411.     print "</form>";
  412. }
  413.  
  414. sub delete {
  415.     $num = $_[0];
  416.  
  417.     open(IN,"< $conf");
  418.     open(OUT,"> $dummy");
  419.  
  420.     while(<IN>) {
  421.         @items = split(/\s+/);
  422.         if ($items[1] eq $_[0]) { print OUT "; $_"; }
  423.         else { print OUT $_; }
  424.     }
  425.     close(IN);
  426.     close(OUT);
  427.     rename($dummy, $conf);
  428.     $message = "Domain deleted.";
  429. }
  430.      
  431. sub addDomain {
  432.     $numTab1 = 2 - length($fld{'newType'})/8;
  433.     $numTab2 = 4 - length($fld{'domain'})/8;
  434.  
  435.     open(OUT,">> $conf");
  436.     print OUT $fld{'newType'};
  437.     for ($i=0;$i<$numTab1;$i++) { print OUT "\t"; }
  438.     print OUT $fld{'domain'};
  439.     if ($fld{'newType'} eq 'primary') {
  440.         for ($i=0;$i<$numTab2;$i++) { print OUT "\t"; }
  441.     } else {
  442.         print OUT " ";
  443.         foreach $arg (@list) {
  444.             print OUT "$arg ";
  445.         }
  446.     }
  447.     print OUT "$fld{'newFile'}\n";
  448.  
  449.     close(OUT);
  450.     $message = "$fld{'domain'} domain added.";
  451. }
  452.  
  453. sub turnOn  { 
  454.     system("/etc/chkconfig", "named", "on");
  455.     $srv_on = 'Yes'; 
  456.     $message = "Named enabled";
  457. }
  458. sub turnOff { 
  459.     system("/etc/chkconfig", "named", "off");
  460.     $srv_on = 'No'; 
  461.     $message = "Named disabled";
  462. }
  463.  
  464. sub getDomains {
  465.     $getDomain = $_[0];
  466.     undef @domainList;
  467.     undef @listServe;
  468.     undef @forwarders, $forwarders;
  469.     $val{'slave'} = "No";
  470.  
  471.     open(IN,"< $conf");
  472.  
  473.     $i = 0;
  474.     while(<IN>) {
  475.         $line = $_;
  476.         @items = split(/\s+/,$line);
  477.         $domain = $items[1];
  478.  
  479.         if ($items[0] eq 'slave') { $val{'slave'} = "Yes"; }
  480.         elsif ($items[0] eq 'forwarders') { 
  481.             for ($i=1;$i<=$#items;$i++) { 
  482.                 push(@forwarders,$items[$i]);
  483.             }
  484.         } elsif ($items[0] eq 'primary' || $items[0] eq 'secondary') {
  485.             push(@domainList,$domain);
  486.             if ($getDomain eq $domain) {
  487.                 $val{'type'} = $items[0];
  488.                 $file = $items[$#items];
  489.                 if ($val{'type'} eq 'secondary') {
  490.                     for ($i=2;$i<$#items;$i++) { push(@listServe,$items[$i]); }
  491.                 }
  492.             }
  493.         } else { next; } # cache not supported yet
  494.     }
  495.     close(IN);
  496.     $val{'forwarders'} = join("\n",@forwarders);  
  497. }
  498.  
  499. sub checkForwarders {
  500.     &getDomains;
  501.     @list = split(/[\n\s]+/,$fld{'forwarders'});
  502.     $newForwarders = join("\n",@list);
  503.     if ($newForwarders ne $val{'forwarders'}) { 
  504.         open(IN,"< $conf");
  505.         open(OUT,"> $dummy");
  506.         while(<IN>) {
  507.             @items = split(/\s+/);
  508.             if ($items[0] ne 'forwarders') { print OUT $_; }
  509.             else { print OUT "; $_"; }
  510.         }
  511.         if (@list) {
  512.             print OUT "forwarders\t@list\n";
  513.         }
  514.         close(IN);
  515.         close(OUT);
  516.         rename($dummy, $conf);
  517.  
  518.         $val{'forwarders'} = join("\n",@list);
  519.     
  520.         $message = "List of other servers that can resolve names edited.";
  521.     }
  522.  
  523. sub getAdd {
  524.     &js_title_block($title,$js_add);
  525.     &header_block("Add New Domain");
  526.  
  527.     if (!$val{'newFile'}) { 
  528.         $val{'newFile'} = "/etc/named.d/db.".$val{'domain'}; 
  529.     }
  530.  
  531.     print "<form name=StandardForm action=$myname method=post onSubmit=\"return runSubmit()\">";
  532.     print "<center><table>";
  533.  
  534.     print qq|<input type=hidden name="domain" value=$val{'domain'}>|;
  535.  
  536.     print "<tr><th align=left>Domain name:</th><td><tt>$val{'domain'}</tt></td></tr>";
  537.     print "<tr><th align=left>Name server type:</th><td><tt>",
  538.         &select('newType',$val{'newType'},'primary','secondary'), "</tt></td></tr>";
  539.  
  540.     print "<tr><th align=left>File name for domain information:</th>";
  541.     print "<td>", &text("newFile",$val{'newFile'},21), "</td>";
  542.     print "</tr>\n";
  543.     
  544.     print "<tr><th align=left valign=top>List of server addresses:</th>";
  545.     print "<td><textarea name=list rows=5 cols=20>",
  546.            $val{'list'},"</textarea></td>";
  547.     print "</tr>\n";
  548.  
  549.     print "</table></center><br>";
  550.  
  551.     print "<i>  Note:  server address list required only for secondary domains.</i><br><br>";
  552.  
  553.     print &js_buttons('doAdd','Ok','onClick="markOK()"','onClick="markOther()"',
  554.         "onClick=\"do_help('$help_page'); return (false)\"");
  555.  
  556.     print "</form>";
  557. }
  558.  
  559. sub generic {
  560.     &js_title_block($title,$js_main);
  561.     &header_block($title);
  562.  
  563.     $val{'newDomain'} = $fld{'newDomain'};
  564.  
  565.     print "<i>$message</i>\n";
  566.  
  567.     print "<form name=DNSForm action=$myname method=post onSubmit=\"return runSubmit()\">\n";
  568.  
  569.     if ($delete) { print "<input type=hidden name=delFile value=$fld{'chosen'}>\n"; }
  570.  
  571.     print "<center><table width=450>";
  572.     print "<tr><th align=left>Enable DNS server:</th><th align=left>\n";
  573.     print &radio('server',$srv_on,'Yes','No');
  574.     print "<br><br></th></tr>\n";
  575.  
  576.     print qq|<tr><th align=left><input type=submit name="add" 
  577.     value="Add New Domain" onClick="markAdd()"></th>\n|;
  578.     print qq|<td>|,&text("newDomain",$val{'newDomain'},19),qq|</td></tr>\n|;
  579.  
  580.     if ($delete) {
  581.         undef @locList;
  582.         foreach $arg (@domainList) {
  583.             if ($fld{'chosen'} ne $arg) { push(@locList,$arg); }
  584.         }
  585.     } else { @locList = @domainList; }
  586.  
  587.     print qq|<tr><th align=left><input type=submit name="edit" 
  588.     value="Edit Selected Domain" onClick="markEdit()"></th>\n|;
  589.     print qq|<td rowspan=2>|, &choice_list(*locList,"chosen",20), qq|</td></tr>\n|;
  590.  
  591.     print qq|<tr><th align=left><input type=submit name="delete" 
  592.     value="Delete Selected Domain" onClick="markDelete()"></th></tr>\n|;
  593.  
  594.     print "<tr><td> </td></tr>\n";
  595.  
  596.     print "<tr><th align=left valign=top>Other servers to contact if <br>
  597.     name cannot be resolved:</th><td>\n";
  598.  
  599.     print "<textarea name=forwarders rows=6 cols=18>$val{'forwarders'}</textarea></td></tr>\n";
  600.  
  601.     print "<tr><th align=left>Limit contact hosts to above:</th><th align=left>\n";
  602.     print &radio('slave',$val{'slave'},'Yes','No');
  603.     print "</th></tr>"; 
  604.  
  605.     print "</table></center><br>\n";    
  606.  
  607.     print &js_buttons('doit','Ok','onClick="markOK()"','onClick="markOther()"',
  608.         "onClick=\"do_help('$help_page'); return (false)\"");
  609.  
  610.     print "</form></body></html>";
  611. }
  612.  
  613.